

compono.ui.Window = compono.Class({
	name:"Window",
	
	title:false,
	description:false,
	
	contentSrc:false,
	contentText:false,
	contentHTML:false,
	contentElement:false,

	className:false,
	
	html:false,
	viewport:false,
	
	modal:false,
	modalClassName:false,
	modalElement:false,
	
	canDrag:true,
	canMinimize:false,
	canHide:false,
	canResize:false,
	events:true,
	persist:false,
	
	openup:false,
	minimized:false,
	
	overflow:false,
	position:"center",
	
	top:"auto",
	left:"auto",
	ZINDEX:100,
	zIndex:"auto",
	width:"auto",
	height:"auto",
	contentWidth:"auto",
	contentHeight:"auto",

	INSTANCES:false,
	
	dragDrop:false,

	constructor:function(proto)
	{
		if(proto){
			var p;
			for(p in proto){
				this[p] = proto[p]
			}
		};
	},
	
	event:function(name,args)
	{
		if(!this.hasOwnProperty(arguments[0]))
		{
			return
		};
		
		var $function = this[arguments[0]];
			
			Array.prototype.shift.call(arguments);
			
		return $function.apply(this,arguments);
	},
	createPath:function(n){
		//creating path;
		var c = this.$(n).getChildren();
		for(var i=0; i<c.length; i++){
			n[(c[i].id || (c[i].className.split(" ")[0]) || c[i].nodeName)] = c[i];
			arguments.callee.call(this,c[i]);
		};
		
		return this;
	},
	content:function(c)
	{
		this.html.body.content.innerHTML = c;
		return this;
	},
	setContent:function(element){

		if(this.html){
			this.html.remove();	
		};
	
	
		//Reference to a HTML Node which is a complete window
		if(element)
		{
			if(this.$(element).hasClassName("window"))
			{
				this.html = element;
			}
			else
			{
				this.html = this.$(this.build());
				var o = element.parentNode ? element.parentNode.removeChild(element) : element;
				this.html.body.content.appendChild( o )
			};
			
		}
		else
		{
			this.html = this.$(this.build());
			this.createPath(this.html)
			
			//HTML String which is the window content;
			if(this.contentHTML)
			{
				this.content(this.contentHTML);
			}
			//SRC to get the content with ajax
			else if(this.contentSrc)
			{
				if(typeof(this.contentSrc)=="string")
				{
					this.request = this.$R(this.contentSrc,{
										window:this,
										onLoading:function(){
											this.window.html.appendClassName("loading");
										},
										onSuccess:function(){
											this.window.html.removeClassName("loading");
											this.window.content(this.response);
										}
									})
				}
				else if(	this.contentSrc instanceof compono.Ajax ||
							this.contentSrc instanceof compono.Ajax.Request ||
							this.contentSrc instanceof compono.Ajax.Updater )
				{
					this.request = this.contentSrc;
				};
			
				this.request.run();
			}
			//Text that will be the window content, based on Wiki syntax
			else if(this.contentText)
			{
				this.html.body.content.innerHTML = this.$W(this.content);
			}
			//Reference to an element which is the window content;
			else if(this.contentElement)
			{
				return arguments.callee.call(this,this.contentElement);
			}
			
		};
			
		if(this.title)
		{
			this.html.body.head.titles.innerHTML = this.$W(this.title);
		}
		else if(this.html&&this.html.body&&this.html.body.head&&this.html.body.head.titles)
		{
			this.title = this.html.body.head.titles.innerHTML;
		};
		
		return this.html.windowElement = this;
	},
	run:function(element){

		this.setContent(element);
		
		return this;
	},
	build:function(){
		var d = this.$D();
		d.DIV({"class":"window"},
			d.DIV({"class":"body"},
				d.DIV({"class":"head"},
					d.H2({"class":"titles"}),
					d.DIV({"class":"controls"},
						d.A({"class":"minimize","href":"#minimize"},"_"),
						d.A({"class":"close","href":"#close"},"X")
					)
				),
				d.DIV({"class":"content"})
			)
		);
		return d.render();
	},
	actionButtonsClick:function(event){
		var button, method;

		if(button = this.windowElement.getButtons(event.target))
		{
			//test
			if(this.windowElement.onDefaultAction && this.windowElement.$(button).hasClassName(["action","default"]))
			{
				method =  this.windowElement.onDefaultAction
			}
			else if(this.windowElement.onAction && this.windowElement.$(button).hasClassName("action"))
			{
				method = this.windowElement.onAction
			}
			else if(this.windowElement.onEscape && this.windowElement.$(button).hasClassName("escape"))
			{
				method = this.windowElement.onEscape
			}
			//Execution
			if( method && method.call( this.windowElement, event, button, this ) != false)
			{
				this.windowElement.hide();
				event.preventDefault();
				return false;
			}
		}
	},
	getButtons:function(o){
		o = this.$(o), n = o.nodeName.toLowerCase();
		
		//		console.log($$("span.button, input[type='submit'], input[type='button'], button, a.button", m.html, true))
		
		if(o.parentNode.nodeName.toLowerCase()=="span"&&n=="input"){
			o = this.$(o.parentNode);
		}else if((n=="button"||(n=="input"&&(o.type=="submit"||o.type=="button")))||(n=="a"&&o.hasClassName("button"))||(n=="span"&&o.hasClassName("button"))){
			o = o
		}else{
			o = false;
		};
		return  o;
	},
	focus:function(e){
		if(this.event("onFocus",e)==false){
			return false;
		};
		return this
	},
	blur:function(e){
		if(this.event("onBlur",e)==false){
			return false;
		};
		return this
	},
	show:function(e){

		if(this.event("onShow",e)==false){
			return false;
		};
		
		if(this.className){
			this.html.appendClassName(this.className);
		};
		
		this.html.appendClassName("window-openup");
		
		if(this.zIndex==-1||this.zIndex=="auto"){
			this.zIndex = this.ZINDEX + (this.INSTANCES.length * 10);
		};
		this.html.css("z-index", this.zIndex);
		
		this.INSTANCES.push(this);
		
		if(this.modal){		this.setModal(true)		};
		if(this.position){	this.setPosition()		};
		if(this.overflow){	this.setOverflow()		};
		if(this.resize){	this.setResize()		};
		if(this.fixed){		this.setFixed(true)		};
		
		if(this.canDrag){
			this.dragDrop = this.$DD(this.html,(this.modalElement||document.documentElement||document.body),"boundingbox"); 
			this.dragDrop.getBaseTrigger = function(b){
				return this.$T1("h2",b).parent();
			};
			this.dragDrop.run();
		};
		
		if(this.events!=false){
			this.html.event("#",this.htmlActionEvents);
			this.html.event("ESQ",this.htmlKeyESQ);
			this.html.event("click",this.actionButtonsClick);
		};

		this.openup = true;
		
		return this;
	},
	hide:function(e){
		if(this.event("onHide",e)==false){
			return false
		};
		
		if(this.className){
			this.html.removeClassName(this.className);
		};
		
		this.html.removeClassName("window-openup");

		this.html.removeEvent("#",this.htmlActionEvents);
		this.html.removeEvent("ESQ",this.htmlKeyESQ);
		this.html.removeEvent("click",this.actionButtonsClick);
		
		this.openup = false;

		this.INSTANCES = this.INSTANCES.filter(function(w){
			return this!==w;
		},this)
		
		if(this.modal){	
			this.setModal(false);
		}
		
		return this;
	},
	setModal:function(open){
		if(this.event("onModal",open)==false){
			return;
		};
		this.modalElement = this.$("modal");
		if(!this.modalElement){
			var b = document.body;
			this.modalElement = this.$(b.insertBefore(document.createElement("div"), b.firstChild));
			this.modalElement.id = "modal";
			this.modalElement.className = "modal";
		};
		
		this.modalElement.css("z-index", parseInt(this.html.css("z-index"),10) - 1);
		
		if(open==true){
			this.setModalSize();
			this.modalElement.appendClassName("modal-openup")
			this.html.appendClassName("window-modal", document.body);
			this.html.appendClassName("window-modal", document.body.parentNode);
			this.html.event("keydown",this.windowModalKeyPress);
			this.html.event("keydown",this.documentModalKeyPress,document);
			this.html.event("resize",this.windowResize, window);
		
		}else if(open==false){
			var wz = this.elements.filter(function(w){return w.modal&&w.openup&&this!==w;},this)
			if(wz.length){
				var w = wz.last();
					w.modalElement.css("z-index", parseInt(w.html.css("z-index"),10) - 1);
					return this.modalElement;
			}

			this.modalElement.removeClassName("modal-openup")
			this.html.removeClassName("window-modal", document.body);
			this.html.removeClassName("window-modal", document.body.parentNode);
			this.html.removeEvent("keydown",this.windowModalKeyPress);
			this.html.removeEvent("keydown",this.documentModalKeyPress,document);
			this.html.removeEvent("resize",this.windowResize, window);
		};
		return this.modalElement;
	},
	setModalSize:function(){
		var m = this.modalElement || arguments.callee.modalElement;
		if(m){
			var b = m.viewport();
			m.style.width = (b.totalWidth)+"px";
			m.style.height = (b.totalHeight)+"px";
			if(!arguments.callee.modalElement){
				arguments.callee.modalElement = m;
				m.event("resize",arguments.callee,window);
			}
		};
		return this
	},
	setFixed:function(){
		if(!this.windowScroll.scope){
			this.windowScroll.scope = this;
			this.windowScroll.cords = this.html.cords();
			this.windowScroll();
			this.html.event("scroll",this.windowScroll, window);
		}
	},
	setResize:function(){
		this.windowResize.scope = this;
	},
	setPosition:function(){
		if(this.position){
			var p=this.position.split(" ");
			var hor=p[0], ver=p[1], o=this.html.cords(), v=this.html.viewport(), x,y;
			switch(hor){
				case "left": 				x = 0; break;
				case "right": 				x = v.width - o.width; break;
				case "center": default:		x = (v.width/2) - (o.width/2) + v.base.scrollLeft; break;
			};
			switch(ver){
				case "top": 				y = 0; break;
				case "bottom": 				y = v.height - o.height; break;
				case "center": default:		y = (v.height/2) - (o.height/2) + v.base.scrollTop; break;
			};
			this.html.css("left",x+"px");
			this.html.css("top",y+"px");
		};
	},
	setOverflow:function(){
		if(this.overflow){
			switch(this.overflow){
				case "auto": case "visible": case "fixed":
					this.html.body.content.appendClassName("overflow-"+this.overflow);
			}
		}
	},
	minimize:function(e){
		if(this.event("onMinimize",e)==false){
			return false
		};
		this.html.toggleClassName("window-minimized");
		return this
	},
	maximize:function(e){
		if(this.event("onMaximize",e)==false){
			return false
		};
		this.html.removeClassName("window-minimized");
		return this
	},
	htmlFocus:function(e){
		console.log(this,e)
	},
	documentModalKeyPress:function(e){
		e.stopPropagation();
		e.preventDefault();
	},
	htmlKeyESQ:function(e){
		if(this.windowElement){
			this.windowElement.hide();
		}
	},
	htmlActionEvents:function(e){
		switch(e.action){
			case "close": this.windowElement.hide();
			default: e.preventDefault(); return;
		};
		return true;
	},
	windowModalKeyPress:function(e){
		e.stopPropagation();
	},
	windowResize:function(){
		arguments.callee.scope.setModalSize()
	},
	windowScroll:function(e){
		var s = arguments.callee;
		var b = document.documentElement||document.body;
		s.scope.html.style.top = (s.cords.top + b.scrollTop) + "px";
		s.scope.html.style.left = (s.cords.left + b.scrollLeft) + "px";
	},
	/** *********************************************************************
		MODAL
	**/
	setModal:function(open){
	
		if(this.event("onModal",open)==false){
			return;
		};
		this.modalElement = this.$("modal");
		if(!this.modalElement){
			var b = document.body;
			this.modalElement = this.$(b.insertBefore(document.createElement("div"), b.firstChild));
			this.modalElement.id = "modal";
			this.modalElement.className = "modal";
		};
		
		this.modalElement.css("z-index", parseInt(this.html.css("z-index"),10) - 1);
		
		if(open==true){
			this.setModalSize(this.modalElement);
			this.modalElement.appendClassName("modal-openup")
			if(this.modalClassName){
				this.modalElement.appendClassName(this.modalClassName)
			}
			this.html.appendClassName("window-modal", document.body);
			this.html.appendClassName("window-modal", document.body.parentNode);
			this.html.event("keydown",this.windowModalKeyPress);
			this.html.event("keydown",this.documentModalKeyPress,document);
			
			this.windowModalResize.scope = this;
			this.html.event("resize", this.windowModalResize, window);
		
		}else if(open==false){
			var wz = this.INSTANCES.filter(function(w){
				return w.modal&&w.openup&&this!==w;
			},this)
			if(wz.length){
				var w = wz.last();
					w.modalElement.css("z-index", parseInt(w.html.css("z-index"),10) - 1);
					return this.modalElement;
			};

			this.modalElement.removeClassName("modal-openup")
			if(this.modalClassName){
				this.modalElement.removeClassName(this.modalClassName)
			}
			this.html.removeClassName("window-modal", document.body);
			this.html.removeClassName("window-modal", document.body.parentNode);
			this.html.removeEvent("keydown",this.windowModalKeyPress);
			this.html.removeEvent("keydown",this.documentModalKeyPress,document);
			this.html.removeEvent("resize", this.windowModalResize, window);
		};
		return this.modalElement;
	},
	setModalSize:function(modalElement){
		var m = this.$( modalElement || this.modalElement || arguments.callee.modalElement );
		if(m){
			var b = m.viewport();
			m.style.width = (b.totalWidth)+"px";
			m.style.height = (b.totalHeight)+"px";
			// if(!arguments.callee.modalElement){
				// arguments.callee.modalElement = m;
				// m.event("resize",arguments.callee,window);
			// }
		};
		return this
	},
	windowModalResize:function(e){
		if(arguments.callee.scope){
			arguments.callee.scope.setModalSize()
		}
	},
	documentModalKeyPress:function(e){
		e.stopPropagation();
		e.preventDefault();
	},
	windowModalKeyPress:function(e){
		e.stopPropagation();
	},
	/** ****************************************************************************************
		Ajax as base window's src
	**/
	reload:function(url){
		if(this.contentSrc && this.request){
			this.request.run(url);
		};
		return this;
	}
});

//Instances array
compono.ui.Window.INSTANCES = [];
compono.ui.Window.prototype.INSTANCES = compono.ui.Window.INSTANCES;